﻿using BUGCOME.Infrastructure.Attribute;
using BUGCOME.Infrastructure.Cache;
using BUGCOME.Model.Common;
using BUGCOME.Model.Common.dto;
using BUGCOME.Service.Common.IServices;

namespace BUGCOME.Service.Common
{
    /// <summary>
    /// 字典数据服务实现类
    /// 实现IDictDataService接口
    /// </summary>
    [AppService(ServiceType = typeof(IDictDataService), ServiceLifetime = LifeTime.Transient)]
    public class DictDataService : BaseService<DictData>, IDictDataService
    {
        /// <summary>
        /// 根据字典编码数组删除字典数据
        /// </summary>
        /// <param name="dictCodes">要删除的字典编码数组</param>
        /// <returns>异步任务，返回删除的数据条数</returns>
        public async Task<long> DeleteDictDataByIdsAsync(long[] dictCodes)
        {
            return await Deleteable().Where(u => dictCodes.Contains(u.Id)).ExecuteCommandAsync();
        }

        /// <summary>
        /// 插入新的字典数据
        /// </summary>
        /// <param name="dict">包含字典数据的实体对象</param>
        /// <returns>异步任务，返回插入后生成的主键ID</returns>
        public async Task<long> InsertDictDataAsync(DictData dict)
        {
            return await Insertable(dict).ExecuteReturnBigIdentityAsync();
        }

        /// <summary>
        /// 根据自定义SQL查询字典数据
        /// 入参为包含SQL的字典类型信息
        /// 返回字典数据集合
        /// </summary>
        public async Task<List<DictData>> SelectDictDataByCustomSqlAsync(DictType dictType)
        {
            return await Context.Ado.SqlQueryAsync<DictData>(dictType?.CustomSql);
        }

        /// <summary>
        ///  异步根据 ID 查询字典数据（带缓存机制）
        /// </summary>
        /// <param name="id"> 参数 id：要查询的字典数据 ID</param>
        /// <returns>逻辑：生成缓存键 CK，检查缓存中是否存在对应数据；若不存在则从数据源查询并缓存 5 单位时长，最终返回结果</returns>
        public async Task<DictData> SelectDictDataByIdAsync(long id)
        {
            string CK = $"SelectDictDataById_{id}";
            if (CacheHelper.GetCache(CK) is not DictData list)
            {
                list = await GetFirstAsync(f => f.Id == id);
                CacheHelper.SetCache(CK, list, 5);
            }
            return list;
        }

        /// <summary>
        /// 查询指定类型的启用字典数据
        /// 结果缓存10分钟，按排序号排序
        /// 返回启用状态的DictData列表
        /// </summary>
        public async Task<List<DictData>> SelectDictDataByTypeAsync(string dictType)
        {
            string CK = $"SelectDictDataByType_{dictType}";

            var list = await Queryable()
                .WithCache(CK, 60 * 10)
                .Where(f => f.Status == "0" && f.DictType == dictType)
                .OrderBy(it => it.DictSort)
                .ToListAsync();

            return list;
        }

        /// <summary>
        /// 根据字典类型列表查询启用字典数据
        /// 结果缓存30分钟，按排序号排序
        /// 返回符合条件的DictData列表
        /// </summary>
        public async Task<List<DictData>> SelectDictDataByTypesAsync(List<string> dicts)
        {
            string CK = $"SelectDictDataByTypes_{dicts}";

            var list = await Queryable()
                 .WithCache(CK, 60 * 30)
                .Where(f => f.Status == "0" && dicts.Contains(f.DictType))
                .OrderBy(it => it.DictSort)
                .ToListAsync();
            return list;
        }

        /// <summary>
        /// 分页查询字典数据列表
        /// 支持按标签、状态、类型筛选
        /// 返回分页包装的DictData集合
        /// </summary>
        public async Task<PagedInfo<DictData>> SelectDictDataListAsync(DictDataQueryDto dto)
        {
            var exp = Expressionable.Create<DictData>();
            exp.AndIF(!string.IsNullOrEmpty(dto.DictLabel), it => it.DictLabel.Contains(dto.DictLabel));
            exp.AndIF(!string.IsNullOrEmpty(dto.Status), it => it.Status == dto.Status);
            exp.AndIF(!string.IsNullOrEmpty(dto.dType), it => it.DictType == dto.dType);
            return await GetPagesAsync(exp.ToExpression(), dto, f => f.DictSort, OrderByType.Asc);
        }

        /// <summary>
        /// 更新字典数据并清除对应缓存
        /// </summary>
        /// <param name="dict">包含更新信息的字典实体（需包含ID用于定位）</param>
        /// <returns>异步任务，返回受影响的行数</returns>
        public Task<long> UpdateDictDataAsync(DictData dict)
        {
            // 根据ID定位数据，更新指定字段（包含更新人、更新时间等）
            var result = UpdateAsync(w => w.Id == dict.Id, it => new DictData()
            {
                Remark = dict.Remark,          // 备注
                UpdateBy = dict.UpdateBy,      // 更新人
                UpdateTime = DateTime.Now,     // 更新时间（取当前时间）
                DictSort = dict.DictSort,      // 排序号
                DictLabel = dict.DictLabel,    // 字典标签
                DictValue = dict.DictValue,    // 字典值
                Status = dict.Status,          // 状态
                CssClass = dict.CssClass,      // CSS样式类
                ListClass = dict.ListClass,    // 列表样式类
                LangKey = dict.LangKey         // 语言键
            });

            // 清除该字典数据的缓存，避免缓存不一致
            CacheHelper.Remove($"SelectDictDataByCode_{dict.Id}");
            return result;
        }

        /// <summary>
        /// 更新字典类型（替换操作）
        /// 将旧字典类型替换为新字典类型
        /// 返回受影响的记录数
        /// </summary>
        public async Task<int> UpdateDictDataTypeAsync(string oldDictType, string newDictType)
        {
            return await Context.Updateable<DictData>()
                .SetColumns(t => new DictData { DictType = newDictType })
                .Where(f => f.DictType == oldDictType)
                .ExecuteCommandAsync();
        }
    }
}